/*
 * Copyright (c) 2009, Servoy-stuff
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 * http://www.fsf.org/licensing/licenses/lgpl.txt
 */
package net.stuff.servoy.beans.svg;

import java.awt.geom.Point2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.svg.SVGPoint;

import com.servoy.j2db.scripting.IScriptObject;

/**
 * @author Seroy Stuff
 * http://www.servoy-stuff.net/
 */
public class MouseTracker implements Serializable, IScriptObject {
	
	private static final long serialVersionUID = 1L;

	private String nodeId;
	private Double x, y;
	private Double initialX, initialY;
	private String related;
	private Integer relatedIndex;
	private String constraintNode;
	
	public transient double radius;
	public transient double currentX, currentY;
	public transient SVGPoint point;
	public transient double scale;
	public transient Point2D.Double trans = new Point2D.Double();
	public transient Point2D.Double client = new Point2D.Double();
	private transient Point2D.Double distance = new Point2D.Double();

		
	public MouseTracker(String id, Double x, Double y, String related, Integer relatedIndex, String constrain) {
		this.nodeId = id;
		this.related = related;
		this.relatedIndex = relatedIndex;
		this.constraintNode = constrain;
		this.initialX = x;
		this.initialY = y;
		resetLocation();
	}
	
	public MouseTracker(Object[] s) {
		if (s != null) {
			try {
				this.nodeId = (s.length > 0) ? (String) s[0] : null;
				Number nb = (s.length > 1) ? (Number) s[1] : null;
				this.initialX = (nb != null) ? new Double(nb.doubleValue()) : null;
				nb = (s.length > 1) ? (Number) s[2] : null;
				this.initialY = (s.length > 2) ? new Double(nb.doubleValue()) : null;
				this.related = (s.length > 3) ? (String) s[3] : null;
				this.relatedIndex = (s.length > 4) ? (Integer) s[4] : null;
				this.constraintNode = (s.length > 5) ? (String) s[5] : null;
			} catch (Exception ex) {}
			resetLocation();
		}
	}
	
	/* (non-Javadoc)
	 * @see com.servoy.j2db.scripting.IScriptObject#getAllReturnedTypes()
	 */
	public Class[] getAllReturnedTypes() {
		return null;
	}

	/* (non-Javadoc)
	 * @see com.servoy.j2db.scripting.IScriptObject#getParameterNames(java.lang.String)
	 */
	public String[] getParameterNames(String methodName) {
		return null;
	}

	/* (non-Javadoc)
	 * @see com.servoy.j2db.scripting.IScriptObject#getSample(java.lang.String)
	 */
	public String getSample(String methodName) {
		return null;
	}

	/* (non-Javadoc)
	 * @see com.servoy.j2db.scripting.IScriptObject#getToolTip(java.lang.String)
	 */
	public String getToolTip(String methodName) {
		return null;
	}

	/* (non-Javadoc)
	 * @see com.servoy.j2db.scripting.IScriptObject#isDeprecated(java.lang.String)
	 */
	public boolean isDeprecated(String methodName) {
		return false;
	}
	
	public MouseTracker set(String id) {
		return set(id, x, y, related, relatedIndex, constraintNode);
	}
	public MouseTracker js_set(String id) {
		return set(id);
	}
	
	public MouseTracker set(String id, Double x, Double y) {
		return set(id, x, y, related, relatedIndex, constraintNode);
	}
	public MouseTracker js_set(String id, Double x, Double y) {
		return js_set(id, x, y);
	}
	
	public MouseTracker set(String id, Double x, Double y, String related) {
		return set(id, x, y, related, relatedIndex, constraintNode);
	}
	public MouseTracker js_set(String id, Double x, Double y, String related) {
		return set(id, x, y, related);
	}
	
	public MouseTracker set(String id, Double x, Double y, String related, Integer relatedIndex) {
		return set(id, x, y, related, relatedIndex, constraintNode);
	}
	public MouseTracker js_set(String id, Double x, Double y, String related, Integer relatedIndex) {
		return set(id, x, y, related, relatedIndex);
	}
	
	public MouseTracker set(String id, Double x, Double y, String related, Integer relatedIndex, String constrain) {
		this.nodeId = id;
		this.related = related;
		this.relatedIndex = relatedIndex;
		this.constraintNode = constrain;
		this.initialX = x;
		this.initialY = y;
		resetLocation();
		return this;
	}
	public MouseTracker js_set(String id, Double x, Double y, String related, Integer relatedIndex, String constrain) {
		return set(id, x, y, related, relatedIndex, constrain);
	}
	
	public MouseTracker setLocation(double x, double y) {
		setX(new Double(x));
		setY(new Double(y));
		return this;
	}
	public MouseTracker js_setLocation(double x, double y) {
		return setLocation(x, y);
	}

	/**
	 * @return the nodeId
	 */
	public String getNodeId() {
		return this.nodeId;
	}
	public String js_getNodeId() {
		return getNodeId();
	}
	/**
	 * @param nodeId the nodeId to set
	 */
	public void setNodeId(String nodeId) {
		this.nodeId = nodeId;
	}
	public void js_setNodeId(String nodeId) {
		setNodeId(nodeId);
	}
	
	/**
	 * @return the related
	 */
	public String getRelated() {
		return this.related;
	}
	public String js_getRelated() {
		return getRelated();
	}
	/**
	 * @param related the related to set
	 */
	public void setRelated(String related) {
		this.related = related;
	}
	public void js_setRelated(String related) {
		setRelated(related);
	}
	
	/**
	 * @return the relatedIndex
	 */
	public Integer getRelatedIndex() {
		return this.relatedIndex;
	}
	public Integer js_getRelatedIndex() {
		return getRelatedIndex();
	}
	/**
	 * @param relatedIndex the relatedIndex to set
	 */
	public void setRelatedIndex(Integer relatedIndex) {
		this.relatedIndex = relatedIndex;
	}
	public void js_setRelatedIndex(Integer relatedIndex) {
		setRelatedIndex(relatedIndex);
	}
	/**
	 * @return the x
	 */
	public synchronized Double getX() {
		return this.x;
	}
	public Double js_getX() {
		return getX();
	}
	/**
	 * @param x the x to set
	 */
	public synchronized void setX(Double x) {
		this.x = x;
	}
	public void js_setX(Double x) {
		setX(x);
	}
	
	/**
	 * @return the y
	 */
	public synchronized Double getY() {
		return this.y;
	}
	public Double js_getY() {
		return getY();
	}
	/**
	 * @param y the y to set
	 */
	public synchronized void setY(Double y) {
		this.y = y;
	}
	public void js_setY(Double y) {
		setY(y);
	}
	
	public Point2D.Double calculatePoint() {
		
		double nowToX = (client.getX() - trans.getX()) / scale;
		double nowToY = (client.getY() - trans.getY()) / scale;
		
		double px = nowToX - distance.getX();
		double py = nowToY - distance.getY();
		
		Point2D.Double p = new Point2D.Double(px, py);
		p.setLocation(px, py);
		
		setX(new Double(p.getX()));
		setY(new Double(p.getY()));
		
		return p;
	}

	public void calculateDistance() {		
		double nowToX = (client.getX() - trans.getX()) / scale;
		double nowToY = (client.getY() - trans.getY()) / scale;

		double dx = nowToX - currentX;
		double dy = nowToY - currentY;
		
		distance.setLocation(dx, dy);
	}
	
	public void saveLocation() {
		this.initialX = getX();
		this.initialY = getY();
	}
	
	public void resetLocation() {
		setX(getInitialX());
		setY(getInitialY());
	}

	/**
	 * @return the initialX
	 */
	public Double getInitialX() {
		return this.initialX;
	}
	public Double js_getInitialX() {
		return getInitialX();
	}
	/**
	 * @param initialX the initialX to set
	 */
	public void setInitialX(Double initialX) {
		this.initialX = initialX;
		setX(initialX);
	}
	public void js_setInitialX(Double initialX) {
		setInitialX(initialX);
	}
	
	/**
	 * @return the initialY
	 */
	public Double getInitialY() {
		return this.initialY;
	}
	public Double js_getInitialY() {
		return getInitialY();
	}
	/**
	 * @param initialY the initialY to set
	 */
	public void setInitialY(Double initialY) {
		this.initialY = initialY;
		setY(initialY);
	}
	public void js_setInitialY(Double initialY) {
		setInitialY(initialY);
	}
	
	/**
	 * @return the constraintNode
	 */
	public String getConstraintNode() {
		return this.constraintNode;
	}
	public String js_getConstraintNode() {
		return getConstraintNode();
	}
	/**
	 * @param constrainToParent the constraintNode to set
	 */
	public void setConstraintNode(String constraintNode) {
		this.constraintNode = constraintNode;
	}
	public void js_setConstraintNode(String constraintNode) {
		setConstraintNode(constraintNode);
	}
	
	public Object[] getParameters() {
		List liste = new ArrayList(); 
		liste.add(getNodeId());
		liste.add(getInitialX());
		liste.add(getInitialY());
		liste.add(getRelated());
		liste.add(getRelatedIndex());
		liste.add(getConstraintNode());
		return liste.toArray();
	}
	public Object[] js_getParameters() {
		return getParameters();
	}
}
